Проект: VC принимаются только подписанными и проверяются (R3)

Для обсуждения с Димой и Ромой (проверка сертификатов и PKI — у них). Срез: develop 8d4f3df5a + ветка feature/todo-261015-2253-did-signed-ops. Не реализовано.

Как сейчас

  • POST /v1/credentials принимает запрос, а не VC: сервис сам собирает credential (buildCredential), подписи нет ни у кого. verify проверяет только реестр (issuer/subject DID существуют, VC не отозван, срок), cryptographicallyVerified всегда false, proof: not_checked.

  • identity-сервис выпускает VC персон через vcService.Create от имени did:i:is:identity-system.

Что дала ветка и на что опереться

  • pkg/didkey — разбор и проверка ключей, x5c;

  • pkg/didproof — compact JWS (EdDSA/ES*/RS256/PS256) и реестр верификаторов с местом под ГОСТ;

  • история DID с проверкой — можно взять ключ издателя на момент выпуска VC;

  • у identity-системы теперь может быть настоящий ключ (IDENTITY_SYSTEM_KEY) — ей есть чем подписывать.

Формат подписи VC — развилка

A. VC-JOSE (application/vc+jwt)

B. Data Integrity (eddsa-jcs-2022, ecdsa-jcs-2019)

Что это

VC — payload JWS, подпись снаружи

proof внутри JSON VC, канонизация JCS (RFC 8785)

Код

переиспользует didproof почти целиком

нужна JCS-канонизация + формат proof

Несколько подписей (L1 + УКЭП L3)

JWS JSON General Serialization (RFC 7515 §7.2)

proof set — штатно

ГОСТ

новый alg через Register

новый cryptosuite

Выборочное раскрытие потом

SD-JWT VC

BBS — тяжелее

Совместимость

EBSI/EUDI-кошельки — JOSE/SD-JWT

VC Data Model 2.0 — оба

Рекомендация: A (VC-JOSE) — тот же механизм, что у операций DID, меньше кода, ГОСТ подключается одинаково, путь к SD-JWT. Если статья/партнёры требуют proof set в JSON — B, но это +1–2 дня.

Предлагаемое поведение

  1. POST /v1/credentials с Content-Type: application/vc+jwt — тело = compact JWS, payload = VC.

    • kid — DID URL ключа из assertionMethod издателя (iss == issuer VC);

    • ключ берётся из версии DID издателя, действовавшей на validFrom; деактивированный издатель — отказ;

    • есть x5c — цепочка и статус сертификата проверяются PKI-сервисом (Дима/Рома), не нами;

    • VC сохраняется как есть (JWS), credential — разобранный payload.

  2. Старый JSON-запрос — только в режиме VC_PROOF=optional (как DID_OPERATION_PROOF); в required — 401.

  3. Выпуск от имени системы (identity): сервис собирает VC и сам подписывает ключом IDENTITY_SYSTEM_KEY — proof появляется и у этих VC.

  4. verify: cryptographicallyVerified=true, checks.proof=valid|invalid, checks.issuerKey, checks.certificate (ответ PKI-сервиса).

  5. VC от ИИ-агента о его runtime (R7) — тот же путь: издатель = DID агента, ключ из его assertionMethod; плюс правило мандата (в силу — после подтверждения организацией).

Вопросы

  1. Формат A или B (и нужна ли совместимость с конкретным кошельком/партнёром)?

  2. API PKI-сервиса для проверки x5c: синхронный вызов на каждый verify или кэш статусов?

  3. ГОСТ: подпись VC через cspgw-svc на стороне издателя — кто издатели с ГОСТ (организации, УЦ)?

  4. Хранить ли JWS целиком в БД VC (да, предлагаю — для повторной проверки, как тело операций DID).

Объём (оценка)

A: 2–3 дня (приём JWS, проверка по истории DID, подпись системой, verify, тесты, сценарий); B: +1–2 дня. Интеграция проверки сертификатов — по готовности API PKI.

Журнал изменений

Дата

Перечень изменений

Автор

2026-11-05

Перенесён из архива DID-VC-итоги-2026-11-03 без изменения содержания.

Дис